package com.example.smartwaterapi.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.smartwaterapi.common.api.RestApiResponse;
import com.example.smartwaterapi.entity.User;
import com.example.smartwaterapi.security.SecurityUser;
import com.example.smartwaterapi.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.springframework.util.StringUtils;
import org.springframework.security.core.Authentication;
import java.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.List;

/**
 * 用户控制器
 */
@Tag(name = "用户管理API", description = "用户信息管理相关接口")
@RestController
@RequestMapping("/")
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 更新用户头像
     */
    @PutMapping("/avatar")
    public RestApiResponse<String> updateAvatar(@RequestParam("userId") Long userId, @RequestParam("avatar") String avatar) {
        try {
            if (userId == null || !StringUtils.hasText(avatar)) {
                return RestApiResponse.badRequest("参数无效");
            }
            
            User user = userService.getById(userId);
            if (user == null) {
                return RestApiResponse.notFound("用户不存在");
            }
            
            User updateUser = new User();
            updateUser.setId(userId);
            updateUser.setAvatar(avatar);
            updateUser.setUpdatedAt(LocalDateTime.now());
            
            boolean result = userService.updateById(updateUser);
            if (result) {
                return RestApiResponse.ok("更新头像成功", avatar);
            } else {
                return RestApiResponse.error("更新头像失败");
            }
        } catch (Exception e) {
            log.error("更新头像异常", e);
            return RestApiResponse.error("更新头像失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户信息
     */
    @GetMapping("/profile")
    public RestApiResponse<User> getProfile(@RequestParam(value = "userId", required = false) Long userId) {
        try {
            // 如果没有提供userId，则从SecurityContext中获取
            if (userId == null) {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (authentication != null && authentication.getPrincipal() instanceof SecurityUser) {
                    SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
                    userId = Long.valueOf(securityUser.getUserId());
                }
            }
            
            if (userId == null) {
                return RestApiResponse.unauthorized("未登录");
            }
            
            User user = userService.getById(userId);
            if (user == null) {
                return RestApiResponse.notFound("用户不存在");
            }
            
            // 移除敏感信息
            user.setUnlockPassword(null);
            user.setPasswordSalt(null);
            
            return RestApiResponse.ok(user);
        } catch (Exception e) {
            log.error("获取用户信息异常", e);
            return RestApiResponse.error("获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前登录用户的个人资料
     */
    @Operation(summary = "获取当前用户资料", description = "获取当前登录用户的详细信息")
    @GetMapping("/api/user/profile")
    public RestApiResponse<User> getCurrentUserProfile() {
        // 从SecurityContext中获取当前登录用户
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof SecurityUser) {
            SecurityUser securityUser = (SecurityUser) principal;
            User user = securityUser.getUser();
            // 记录用户ID
            System.out.println("获取用户资料：用户ID=" + user.getId());
            
            // 重新从数据库加载最新数据
            User freshUser = userService.getById(user.getId());
            if (freshUser != null) {
                // 如果从数据库加载的用户ID为null，使用SecurityUser中的ID
                if (freshUser.getId() == null) {
                    freshUser.setId(user.getId());
                    System.out.println("修复用户ID：从SecurityUser中恢复ID=" + user.getId());
                }
                // 清除敏感信息
                freshUser.setUnlockPassword(null);
                freshUser.setPasswordSalt(null);
                freshUser.setSessionKey(null);
                return RestApiResponse.ok(freshUser);
            }
        } else {
            System.out.println("获取用户资料失败：未找到认证信息，Principal类型=" + 
                (principal != null ? principal.getClass().getName() : "null"));
        }
        return RestApiResponse.unauthorized("获取用户信息失败");
    }
    
    /**
     * 更新当前登录用户的个人资料
     */
    @Operation(summary = "更新当前用户资料", description = "更新当前登录用户的基本信息")
    @PutMapping("/api/user/profile")
    public RestApiResponse<User> updateCurrentUserProfile(@RequestBody User userUpdate, @RequestHeader(value = "X-Update-Profile", required = false) String isUpdateProfile) {
        // 从SecurityContext中获取当前登录用户
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof SecurityUser) {
            SecurityUser securityUser = (SecurityUser) principal;
            User currentUser = securityUser.getUser();
            
            // 设置ID，确保更新的是当前用户
            userUpdate.setId(currentUser.getId());
            
            // 检查是否有特殊标记，表示这是从小程序发来的更新用户资料请求
            boolean isSpecialUpdate = "true".equals(isUpdateProfile);
            log.info("更新用户资料请求: userId={}, isSpecialUpdate={}, wxOpenid={}, unionid={}", 
                    currentUser.getId(), isSpecialUpdate, 
                    userUpdate.getWxOpenid() != null ? "非空" : "null", 
                    userUpdate.getUnionid() != null ? "非空" : "null");
            
            // 不允许更新的敏感字段设为null
            userUpdate.setUnlockPassword(null);
            userUpdate.setPasswordSalt(null);
            userUpdate.setSessionKey(null);
            
            // 仅在非特殊更新时阻止更新这些字段
            if (!isSpecialUpdate) {
                userUpdate.setOpenid(null);
                userUpdate.setUnionid(null);
                userUpdate.setWxOpenid(null); // 普通请求不允许更新公众号openid
            } else {
                log.info("特殊更新请求，允许更新 unionid 和 wx_openid 字段");
                // 保留 unionid, wx_openid 和 openid 字段，允许更新
                // 注意：不要设置为null，保持原有值
            }
            
            // 如果是特殊更新且包含公众号openid，直接调用专门的方法更新
            if (isSpecialUpdate && userUpdate.getWxOpenid() != null) {
                log.info("检测到公众号openid更新请求，调用专门的方法更新: userId={}, wxOpenid={}", 
                        currentUser.getId(), userUpdate.getWxOpenid());
                
                boolean success = userService.updateWxOpenid(currentUser.getId(), userUpdate.getWxOpenid());
                if (success) {
                    log.info("公众号openid更新成功: userId={}", currentUser.getId());
                    // 获取更新后的用户信息
                    User updatedUser = userService.getById(currentUser.getId());
                    // 清除敏感信息
                    updatedUser.setUnlockPassword(null);
                    updatedUser.setPasswordSalt(null);
                    updatedUser.setSessionKey(null);
                    return RestApiResponse.ok(updatedUser);
                } else {
                    log.error("公众号openid更新失败: userId={}", currentUser.getId());
                    return RestApiResponse.error("更新用户信息失败");
                }
            }
            
            // 检查是否有任何字段需要更新
            boolean hasFieldsToUpdate = false;
            
            // 使用反射检查是否有任何非null字段需要更新
            try {
                for (Field field : User.class.getDeclaredFields()) {
                    field.setAccessible(true);
                    if (field.get(userUpdate) != null && 
                        !field.getName().equals("id") && 
                        !field.getName().equals("serialVersionUID")) {
                        hasFieldsToUpdate = true;
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("检查更新字段异常", e);
            }
            
            if (!hasFieldsToUpdate) {
                log.warn("用户资料更新请求没有任何字段需要更新: userId={}", currentUser.getId());
                // 获取当前用户信息并返回
                User currentUserInfo = userService.getById(currentUser.getId());
                // 清除敏感信息
                currentUserInfo.setUnlockPassword(null);
                currentUserInfo.setPasswordSalt(null);
                currentUserInfo.setSessionKey(null);
                return RestApiResponse.ok(currentUserInfo);
            }
            
            // 更新用户信息
            userUpdate.setUpdatedAt(LocalDateTime.now()); // 添加更新时间，确保至少有一个字段更新
            boolean success = userService.updateById(userUpdate);
            if (success) {
                log.info("用户资料更新成功: userId={}, isSpecialUpdate={}", currentUser.getId(), isSpecialUpdate);
                // 获取更新后的用户信息
                User updatedUser = userService.getById(currentUser.getId());
                // 清除敏感信息
                updatedUser.setUnlockPassword(null);
                updatedUser.setPasswordSalt(null);
                updatedUser.setSessionKey(null);
                return RestApiResponse.ok(updatedUser);
            } else {
                log.error("用户资料更新失败: userId={}", currentUser.getId());
            }
        }
        return RestApiResponse.unauthorized("更新用户信息失败");
    }

    /**
     * 更新用户信息
     */
    @Operation(summary = "更新用户信息", description = "根据用户ID更新用户基本信息")
    @PutMapping("/api/user/{id}")
    public RestApiResponse<Boolean> updateUser(
            @Parameter(description = "用户ID") @PathVariable Long id,
            @Parameter(description = "用户信息") @RequestBody User user) {
        user.setId(id);
        boolean success = userService.updateById(user);
        if (success) {
            return RestApiResponse.ok(true);
        }
        return RestApiResponse.error("更新用户信息失败");
    }

    /**
     * 更新用户饮水目标
     */
    @Operation(summary = "设置每日饮水目标", description = "设置用户每日饮水目标量（毫升）")
    @PutMapping("/api/user/{id}/daily-goal")
    public RestApiResponse<Boolean> updateDailyGoal(
            @Parameter(description = "用户ID") @PathVariable Long id,
            @Parameter(description = "每日目标(ml)", example = "2000") @RequestParam Integer dailyGoal) {
        if (dailyGoal <= 0) {
            return RestApiResponse.badRequest("饮水目标必须大于0");
        }
        boolean success = userService.updateDailyGoal(id, dailyGoal);
        if (success) {
            return RestApiResponse.ok(true);
        }
        return RestApiResponse.error("更新饮水目标失败");
    }

    /**
     * 更新用户提醒设置
     */
    @Operation(summary = "设置饮水提醒", description = "开启或关闭饮水提醒，并设置提醒间隔")
    @PutMapping("/api/user/{id}/reminder-settings")
    public RestApiResponse<Boolean> updateReminderSettings(
            @Parameter(description = "用户ID") @PathVariable Long id,
            @Parameter(description = "是否启用提醒(0-关闭,1-开启)") @RequestParam Integer enabled,
            @Parameter(description = "提醒间隔(分钟)", example = "60") @RequestParam(required = false) Integer interval) {
        boolean success = userService.updateReminderSettings(id, enabled, interval);
        if (success) {
            return RestApiResponse.ok(true);
        }
        return RestApiResponse.error("更新提醒设置失败");
    }

    /**
     * 分页查询用户列表
     */
    @Operation(summary = "分页查询用户列表", description = "分页获取用户列表，支持关键字搜索")
    @GetMapping("/list")
    public RestApiResponse<Page<User>> listUsers(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") Integer pageSize,
            @Parameter(description = "搜索关键字（昵称或手机号）") @RequestParam(required = false) String keyword) {
        Page<User> userPage = userService.listUsers(pageNum, pageSize, keyword);
        return RestApiResponse.ok(userPage);
    }

    /**
     * 获取用户信息
     */
    @Operation(summary = "获取用户信息", description = "根据用户ID获取用户详细信息")
    @GetMapping("/user/{userId}")
    public RestApiResponse<User> getUserInfo(@Parameter(description = "用户ID") @PathVariable Long userId) {
        try {
            if (userId == null) {
                return RestApiResponse.badRequest("用户ID不能为空");
            }
            
            User user = userService.getById(userId);
            if (user == null) {
                return RestApiResponse.notFound("用户不存在");
            }
            
            // 不返回敏感信息
            user.setPasswordSalt(null);
            user.setUnlockPassword(null);
            user.setSessionKey(null);
            
            return RestApiResponse.ok("获取用户信息成功", user);
        } catch (Exception e) {
            log.error("获取用户信息失败: userId={}", userId, e);
            return RestApiResponse.error("获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 修改当前登录用户的密码
     */
    @Operation(summary = "修改密码", description = "修改当前登录用户的密码")
    @PutMapping("/user/password")
    public RestApiResponse<Boolean> changePassword(@Valid @RequestBody ChangePasswordRequest request) {
        // 从SecurityContext中获取当前登录用户
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof SecurityUser) {
            SecurityUser securityUser = (SecurityUser) principal;
            User currentUser = securityUser.getUser();
            
            // 验证旧密码是否正确
            if (!passwordEncoder.matches(request.getOldPassword(), currentUser.getUnlockPassword())) {
                return RestApiResponse.badRequest("原密码不正确");
            }
            
            // 更新密码 - 转换Long类型的userId为String
            boolean success = userService.updatePassword(String.valueOf(currentUser.getId()), request.getNewPassword());
            if (success) {
                return RestApiResponse.ok(true);
            }
        }
        return RestApiResponse.error("修改密码失败");
    }
    
    /**
     * 密码修改请求
     */
    @Data
    public static class ChangePasswordRequest {
        @NotBlank(message = "原密码不能为空")
        private String oldPassword;
        
        @NotBlank(message = "新密码不能为空")
        private String newPassword;
    }
}
